#include "BitImage.h"
#include <stdio.h>
#include <string.h>

BitImage::BitImage(std::string path)
{
    file_name = path;
    status = IMAGE_NOT_INIT;
    inverted = true;

    do
    {
        /* 打开文件 */
        if (nullptr == (file = fopen(file_name.c_str(), "r")))
        {
            status = IMAGE_NO_FOUND;
            break;
        }
        /* 读取 BMP 文件头 */
        if (sizeof(BmpFileHeader) != fread(&file_h, 1, sizeof(BmpFileHeader), file))
        {
            status = IMAGE_ILLEGAL;
            fclose(file);
            file = nullptr;
            break;
        }
        if (0 != memcmp(file_h.type, "BM", 2))
        {
            status = IMAGE_ILLEGAL;
            fclose(file);
            file = nullptr;
            break;
        }
        /* 读取位图信息头 */
        if (sizeof(BmpInfoHeader) != fread(&info_h, 1, sizeof(BmpInfoHeader), file))
        {
            status = IMAGE_ILLEGAL;
            fclose(file);
            file = nullptr;
            break;
        }
        status = IMAGE_OK;
        image_seek = 0;
        line_bytes = info_h.width * info_h.bpp / 8;

        if(info_h.height < 0)       //图片高度小于0为正向位图
        {
            inverted = false;
            info_h.height = -info_h.height;
        }

        image_info.width = info_h.width;
        image_info.height = info_h.height;
        image_info.bpp = info_h.bpp;
        image_info.srcBpp = image_info.bpp;

    } while (0);
}

BitImage::~BitImage()
{
    if (file != nullptr)
        fclose(file);
}

void BitImage::GetImage(unsigned char *buf, unsigned long line)
{
    if (buf == NULL || line <= 0 || status == IMAGE_NOT_INIT)
        return;

    if (image_seek == 0)
    {
        if (-1 == fseek(file, file_h.offset, SEEK_SET))
        {
            perror("lseek error");
            return;
        }
    }

    if(inverted == true)
    {
        for(int i = line; i > 0; i--)
        {
            unsigned char *p = buf + line_bytes * (i - 1);

            fread(p, line_bytes, 1, file);
        }
    }
    else
        fread(buf, line * line_bytes, 1, file);
}

unsigned long BitImage::GetImage()
{
    return file_h.offset;
}


static unsigned char *BitImageZoom(int w, int h, unsigned char *bmpin, int zoomw, int zoomh, int bpp)
    {
        int bmp_h = zoomh;
        int bmp_w = zoomw;
        int bytes = bpp / 8;

        float zoom = (float)zoomh / bmp_h;

        unsigned char *bmpout = (unsigned char *)malloc(bmp_h * bmp_w * bytes);
        unsigned char *pucDest;
        unsigned char *pucSrc;
        unsigned long dwsrcX;
        unsigned long dwsrcY;

        for (int i = 0; i < bmp_h; i++)
        {
            dwsrcY = i * h / bmp_h;
            pucDest = bmpout + i * bmp_w * bytes;
            pucSrc = bmpin + dwsrcY * w * bytes;
            for (int j = 0; j < bmp_w; j++)
            {
                dwsrcX = j * w / bmp_w;
                memcpy(pucDest + j * bytes, pucSrc + dwsrcX * bytes, bytes);
            }
        }

        return bmpout;
    }